<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="iyTOf" id="iyTOf"><span data-lake-id="u66e76305" id="u66e76305">典型回答</span></h1>
  <p data-lake-id="u25a5af69" id="u25a5af69"><br></p>
  <p data-lake-id="uf23fed2b" id="uf23fed2b"><span data-lake-id="u7e579b9b" id="u7e579b9b">最大努力通知、MQ事务消息以及本地消息表都是依赖MQ实现最终一致性的方案。其中本地消息表和MQ事务消息其实是可靠消息最终一致性的两种具体实现。</span></p>
  <p data-lake-id="ucf23c678" id="ucf23c678"><span data-lake-id="u04992c2c" id="u04992c2c">​</span><br></p>
  <p data-lake-id="u9061d470" id="u9061d470"><br></p>
  <p data-lake-id="u4764170a" id="u4764170a"><span data-lake-id="u2263862a" id="u2263862a">这三者中，</span><strong><span data-lake-id="ua662175f" id="ua662175f">方案最简单的肯定是最大努力通知</span></strong><span data-lake-id="u7e3f1748" id="u7e3f1748">，因为他不需要保证消费者一定能接收到，只是尽自己最大的努力去通知就行了。最多就是在发消息的地方加一个重试的机制。</span></p>
  <p data-lake-id="udf11ca6f" id="udf11ca6f"><span data-lake-id="u741f734a" id="u741f734a">​</span><br></p>
  <p data-lake-id="ubcc58b2a" id="ubcc58b2a"><span data-lake-id="u3a322ee3" id="u3a322ee3">但是</span><strong><span data-lake-id="u57d335ae" id="u57d335ae">这个方案缺点也很明显，那就是可能会导致消息的重复和丢失</span></strong><span data-lake-id="uadb55419" id="uadb55419">，这个比较容易理解。</span></p>
  <p data-lake-id="u439bdf9a" id="u439bdf9a"><span data-lake-id="u3b6dd4c4" id="u3b6dd4c4">​</span><br></p>
  <p data-lake-id="u4497651b" id="u4497651b"><span data-lake-id="u8c64d552" id="u8c64d552">虽然最大努力通知也是一种最终一致性的方案，但是他的一致性保障并没有那么强，所以他不适合用在一些一致性要求较高的场景。只适合用在消息丢了也无所谓的场景。</span><u><span data-lake-id="u00e9c97f" id="u00e9c97f">比如说下单后邮件通知、开通后发送欢迎短信之类的业务场景。</span></u></p>
  <p data-lake-id="ub8ee1f42" id="ub8ee1f42"><u><span data-lake-id="ud5c674e2" id="ud5c674e2">​</span></u><br></p>
  <p data-lake-id="ud6e34ac0" id="ud6e34ac0"><span data-lake-id="u66a4eb95" id="u66a4eb95">MQ事务消息以及本地消息表这两个方案一致性要求更高一些，但是同样方案也要更复杂一些。</span></p>
  <p data-lake-id="u74ac6e35" id="u74ac6e35"><span data-lake-id="u7661b40b" id="u7661b40b">​</span><br></p>
  <p data-lake-id="u16916efe" id="u16916efe"><span data-lake-id="u51f19439" id="u51f19439">MQ事务消息的方案首先要求这个MQ是支持事务消息的，其次对业务代码有侵入性，因为本来只需要发一次消息，用了这个方案之后需要改成发送两个half消息，并且同时还得给MQ提供一个反查的接口。</span></p>
  <p data-lake-id="u1073cb43" id="u1073cb43"><span data-lake-id="u0004850c" id="u0004850c">​</span><br></p>
  <p data-lake-id="u5aca6548" id="u5aca6548"><span data-lake-id="u94a95914" id="u94a95914">本地消息表这个方案对代码的侵入性没那么高，并且不需要MQ支持事务消息，但是他需要单独创建一张本地消息表，并且还需要提供一个定时任务来做轮询。所以他的改造成本也不低。</span></p>
  <p data-lake-id="ubd05bdfb" id="ubd05bdfb"><span data-lake-id="ue84a8071" id="ue84a8071">​</span><br></p>
  <p data-lake-id="ufa0bc941" id="ufa0bc941"><span data-lake-id="u878c728e" id="u878c728e">一般来说，事务消息和本地消息表比较适合于对一致性要求没那么高，不要求强一致，但是也不能丢的一些场景，</span><u><span data-lake-id="u7889f651" id="u7889f651">比如用户下单后给用户增加积分。</span></u></p>
  <p data-lake-id="u02719cf8" id="u02719cf8"><u><span data-lake-id="ua579db22" id="ua579db22">​</span></u><br></p>
  <p data-lake-id="ude7924b1" id="ude7924b1"><span data-lake-id="ucc40394a" id="ucc40394a">一般来说，事务消息和本地消息表两个方案是可以互相替换的，用了事务消息的地方都可以换成本地消息表。但是实际来说，如果MQ支持事务消息，那么可以考虑这个方案，如果公司使用的MQ不支持事务消息，那么就可以考虑本地消息表。</span></p>
  <p data-lake-id="u7f6b3792" id="u7f6b3792"><span data-lake-id="ufaf5024d" id="ufaf5024d">​</span><br></p>
  <p data-lake-id="u9e40566f" id="u9e40566f"><span data-lake-id="uaf850318" id="uaf850318">或者还有些场景有一些消息持久化、或者对账的需求，那么也建议使用本地消息表的方案。</span></p>
  <p data-lake-id="u3dd3973f" id="u3dd3973f"><span data-lake-id="u8698de28" id="u8698de28">​</span><br></p>
 </body>
</html>